# coding=utf-8

from Exploit.BaseExploit import *
from threading import Thread
import requests
from concurrent.futures import ThreadPoolExecutor
requests.packages.urllib3.disable_warnings()
import os
import json
import difflib

abs_path = os.getcwd() + os.path.sep

class CmsScan(Exploit):
    def __init__(self, target, clear_task_list):
        super().__init__()
        self.clear_task_list = clear_task_list
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1'}
        self.strutsTypes = ['VloginUser.action', 'Mail.action', 'code.action', 'reg.action', 'Address.action', '!Index.action', 'login.action', 'Add.action', 'pageslist.action','.Action','Message.action','getMul.action','shouye.action','logout.action','Valid.action','search.action','Magazine.action','news.action','init.action','create.action','index2.action','default.action','welcome.action','Name.action','single.action','updateForm.action','SysStart.action','adminlogin.action','Offportal.action','Buying.action','Success.action','exchange.action','menu.action','airport.action','Email.action','On.action','show.action','tain.action','randomPicture.action','news.do']
        self.target = target
        self.cmsscanlist = []
        with open(abs_path + '/Dict/body.txt', 'r', encoding='utf-8') as a, \
                open(abs_path + '/Dict/head.txt', 'r', encoding='utf-8') as b, \
                open(abs_path + '/Dict/robots.txt', 'r', encoding='utf-8') as d:
            self.body_content = eval(a.read())  # 已经完成
            self.head_content = eval(b.read())  # 已经完成
            self.robots_content = eval(d.read())  # 已经完成

    def write_file(self, web_lists, target, page):
        workbook = openpyxl.load_workbook(abs_path + str(target) + ".xlsx")
        worksheet = workbook.worksheets[page]
        index = 0
        while index < len(web_lists):
            web = list()
            web.append(web_lists[index]['name'])
            web.append(web_lists[index]['url'])
            web.append(web_lists[index]['cms'])
            worksheet.append(web)
            index += 1
        workbook.save(abs_path + str(target) + ".xlsx")
        workbook.close()

    def exploit(self, http):

        _http = http
        if _http.endswith('/'):
            pass
        else:
            _http = _http + '/'

        # struts框架的探测
        try:
            for strutstype in self.strutsTypes:
                try:
                    UA = self.headers
                    headers = {'User-Agent': UA}
                    req1 = requests.head(url=_http + strutstype, headers=headers, timeout=3, allow_redirects=False)
                    if req1.status_code == 200:
                        # print(_http + strutstype)
                        req1_2 = requests.get(url=_http + strutstype, headers=headers, timeout=3, allow_redirects=False)
                        if '.action' in req1_2.content:
                            self.cmsscanlist.append({
                                'name': 'cms识别',
                                'url': http,
                                'cms': 'struts框架'
                            })
                    else:
                        pass
                except:
                    pass
        except:
            pass

        # shiro框架的探测
        try:
            shiro_headers = self.headers
            shiro_headers['Cookie'] = "rememberMe=11;"
            # print(_http)
            resp = requests.get(_http, headers=self.headers, allow_redirects=False)  # allow_redirects设置为False 要不然重定向的发包导致检测不到
            if 'rememberMe' in str(resp.headers):
                temp_dict = {
                    'name': 'cms识别',
                    'url': http,
                    'cms': 'shiro框架'
                }
                self.cmsscanlist.append(temp_dict)
                return
        except:
            pass

        # thinkphp框架的探测
        try:
            thinkphp_url = '1111111111111111111111111111111-index.html'
            resp = requests.get(_http + thinkphp_url, headers=self.headers, allow_redirects=False)
            # print(_http + thinkphp_url)
            # print(resp.content)
            if 'ThinkPHP' in resp.text or 'WE CAN DO IT JUST THINK' in resp.text:
                self.cmsscanlist.append({
                    'name': 'cms识别',
                    'url': _http + thinkphp_url,
                    'cms': 'thinkphp框架'
                })
                return
        except:
            pass

        # 基于首页源代码中的特征寻找
        try:
            resp = requests.get(url=_http, headers=self.headers, allow_redirects=False, timeout=3, verify=False)

            # 迭代器迭代字典
            for keyword, cms in self.body_content.items():
                if keyword in resp.content.decode('utf-8'):
                    self.cmsscanlist.append({
                        'name': 'cms识别',
                        'url': http,
                        'cms': cms
                    })
                    return
                else:
                    pass

            for keyword, cms in self.head_content.iteritems():
                if keyword in resp.headers:
                    self.cmsscanlist.append({
                        'name': 'cms识别',
                        'url': http,
                        'cms': cms
                    })
                    return
        except:
            pass

        # 根目录robots.txt 文本中的特征判断
        try:
            resp = requests.get(url=_http + 'robots.txt', headers=self.headers, allow_redirects=False, timeout=3, verify=False)
            for robots in self.robots_content:
                if robots in resp.content.decode('utf-8'):
                    self.cmsscanlist.append({
                        'name': 'cms识别',
                        'url': http,
                        'cms': robots
                    })
                    return
        except:
            pass

    def main(self):
        logging.info("CmsScan Start")
        p = ThreadPoolExecutor(10)
        temp_ips = []
        for aaa in self.clear_task_list:
            flag = 0
            if aaa['target'] == 'subdomain':
                for i in temp_ips:
                    if aaa['subdomain'] == i:
                        flag += 1
                if flag == 0:
                    temp_ips.append(aaa['subdomain'])
                    subdomain = aaa['subdomain'].replace('\n', '') if aaa['subdomain'].startswith('http') else 'http://' + aaa['subdomain'].replace('\n', '')
                    if subdomain[-1] != '/':
                        subdomain = subdomain + '/'
                    p.submit(self.exploit, subdomain)
                    print("CMS框架扫描：", subdomain)
        p.shutdown()
        self.write_file(self.cmsscanlist, self.target, 9)


if '__main__' == __name__:
    a = CmsScan('', 'http://news.eeeqi.cn/')
    thread_list = []
    thread_list.append(Thread(target=a.header_index_content_scan, args=()))
    thread_list.append(Thread(target=a.robot_scan, args=()))
    thread_list.append(Thread(target=a.frame_scan, args=()))
    # thread_list.append(Thread(target=a.sub_dir_content_scan, args=()))
    # thread_list.append(Thread(target=a.md5_scan, args=()))

    for t in thread_list:
        t.start()
    for t in thread_list:
        t.join()